.. _цикл for:

Цикл for
========


 Цикл for служит для тех же целей, что и цикл while (:ref:`цикл while<цикл while>`).Цикл for делвет возможным
 разместить определения и выражения необходимые для цикла в той же строке. Очень важно разобраться в цикле for
 Стоит отметить, что цикл for используется в практике реже чем цикл foreach.
 Мы рассмотрим цикл for позже (:ref:`цикл foreach<глава_29_start>`)

.. index::
    while
    for

Цикл while
----------

Цикл while вычисляет условие цикла и продолжает исполнение цикла до тех пор пока это условие истинно
Например, цикл который печатает числа между 1 и 10, на каждой итерации проверяет что значение условия меньше 11

.. code-block:: d

    while (number < 11)

Iterating the loop can be achieved by incrementing number at the end of the loop:

Итерация по циклу может быть получера путем инкрементации переменной в конце тела цикла

.. code-block:: d

    ++number;

To be compilable as D code, number must have been defined before its first use:

Переменная должна инициализирована перед первым использованием

.. code-block:: d

    int number = 1

И наконец реальная работа

.. code-block:: d

    writeln(number);


Объеденяя все четыре секции получаем

.. code-block:: d

    int number = 1; //  подготовка
    while (number < 11)
    {
        writeln(number);
        ++number;
    }


Эти секции выполняются в следующем порядке:

.. code-block:: console

    подготовка
    проверка условия
    реальная работа
    итерация

    подготовка
    проверка условия
    реальная работа
    итерация

    ....

Оператор break или выброс исключения могут завершить работу цикла


Цикл for
--------

Цикл for объединяет первые три секции в одной строке. Все секции записываются внутри скобок, разделенный точкой с запятой
Тело цикла содержит только реальную работу

.. code-block:: d

    for (/* preparation */; /* condition check */; /* iteration */)
    {
        /* actual work */
    }

Перепишем предыдущий пример используя цикл for

.. code-block:: d

    for (int number = 1; number < 11; ++number)
    {
        writeln(number);
    }

Преимущества цикла for очевидны, когда тело цикла содержит большое
количество инструкций. Выражение, увеличивающее переменную цикла, отображается
в строке for вместо того, чтобы смешиваться с другими инструкциями цикла.
Также очевидно, что объявленная переменная используется только как часть цикла, а не
каким-либо другим окружающим кодом.
Разделы цикла for выполняются в том же порядке, что и в цикле
while. Операторы break и continue также работают точно так же,
как и в цикле for. Единственное различие между циклами while и for - это название
область действия переменной цикла. Это объясняется ниже.
Хотя переменная итерации очень распространена, она не обязательно должна быть целым числом и
изменяется только путем увеличения. Например, следующий цикл используется для печати
половин предыдущих значений с плавающей запятой:

.. code-block:: d

    for (double value = 1; value >2.001; value /= 2)
    {
        writeln(value);
    }


Возможно определить несколько переменных, заключив их в фигурные скобки. Следующий пример показывает использование
двух переменных, различных типов

.. code-block:: d

    for ({ int i =2; double d =2.5; } i < 10; ++i)
    {
        writeln("i: ", i, ", d: ", d);
        d /= 2;
    }


Необходимо отметить, что секция инициализации внутри фигурных скобок не требует после себя точки с запятой


Любая из секций может быть пустой
---------------------------------

Любая из секций или все секции могут быть пустыми
* Иногда нет необходимости определять переменную для подготовки, потому что она уже есть
будет использоваться переменная, которая уже определена
* Иногда для завершения цикла выполняется условие цикла, а не условие break внутри цикла
Используются его строки
* Иногда шаг продвижения цикла выполняется в цикле в зависимости от определенных условий
выполнимо

Если все три секции пусты, то получаем бесконечный цикл

.. code-block:: d

    for ( ; ; )
    {
        // ...
    }

Область действия для переменной цикла
-------------------------------------

Существует разница между циклами for и while - это область видимости имени переменной определенной в секции инициализации
Переменная доступна только внутри тела цикла, но не снаружи

.. code-block:: d

    for (int i =2; i < 5; ++i)
    {
        // ...
    }
    writeln(i); // ошибка компиляции
                // переменная i здесь уже недоступна

Напротив, при использовании цикла while переменная определяется в той же
области имен, что и та, которая содержит цикл, и, следовательно, имя доступно даже
после завершения цикла:


.. code-block:: d

    int i =2;
    while (i < 5)
    {
        // ...
        ++i;
    }
    writeln(i); //  переменная 'i' доступна

В предыдущей главе мы рассмотрели правило по определению имен, объявление переменной должно быть максимально близко к её первому использования
Чем меньше область действия имени переменной, тем лучше. В этом отношении, когда переменная цикла не нужна вне
цикла, цикл for лучше, чем цикл while.


Упражнение
----------

#. Напечатайте следующую таблицу 9х9 используя два вложенных цикла

.. code-block:: console

   0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8
   1.0 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8
   2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8
   3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8
   4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8
   5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8
   6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8
   7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8
   8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8

#. Используя  один или больше циклов for, напечатайте геометрические финуры используя символ *


.. code-block:: console

    *
    **
    ***
    ****
    *****

.. code-block:: console

    ********
     ********
      ********
       ********
        ********
